/**
 * com.pas.iam.account.resource.NewJDialog.java
 * Copyright (c) 2009 Pas corporation All Rights Reserved.
 */
package com.web.server.common.dao;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Session;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 系统DAO基类
 * <p>
 * 该类实现了数据库的基本添加、删除、修改、查询操作。
 * 系统采用了Spring提供的声明式事务，HibernateTemplate，所以在对数据库进行操作的时候不需要显示的去连接关闭数据库和提交事务。
 * 该接口只是提供了基本的数据库操作，如果存在复杂的操作可以在其子类中对其扩展。
 * 
 * @author  刘红军
 * @version Ver 1.0 2008-03-06 新建
 * @since   PASIAM Ver1.0
 */
public class IamDaoImpl extends HibernateDaoSupport implements IamDao {

	/**
	 * JDBC数据库操作对象
	 * 
	 * @since PASIAM Ver1.0
	 */
	protected NamedParameterJdbcTemplate jdbcTemplate = null;
	
    /**
     * 数据库分页查询工具
     * 
     * @since PASIAM Ver1.0
     */
    protected PageUtil pageUtil = null;
	
	
	/**
	 * 设置数据库分页查询工具
	 *
	 * @param pageUtil the pageUtil to set
	 */
    public void setPageUtil(PageUtil pageUtil){
    	this.pageUtil = pageUtil;
    }
    
	/**
	 * 默认构造方法
	 * 
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */		
	public IamDaoImpl(){
		
	}

	/**
	 * 添加、修改实体对象
	 * 
	 * @param  entity 需要添加或者修改的对象
	 * @return void
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	public void addOrUpdateObject(Object entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	/**
	 * 删除实体对象
	 * 
	 * @param  clazz 需要删除的实体类。
	 * @param  id 需要删除的实体对象的主键。
	 * @return void
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
        public void deleteObject(Class entityClass, Serializable id) {
            getHibernateTemplate().delete(getObject(entityClass, id));
        }

	/**
	 * 批量删除、修改实体对象
	 * 
	 * @param  hql 需要执行的批处理语句
	 * @return int 操作影响到的记录行数。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	public int bulkByNamedParam(final String hql) {
		Integer bulkCount = (Integer) (getHibernateTemplate()
				.execute(new HibernateCallback() {
					public Object doInHibernate(Session session) {
						// 执行批量修改、删除并获得成功的记录个数
						int count = session.createQuery(hql).executeUpdate();
						return count;
					}
				}));
		return bulkCount.intValue();
	}

	/**
	 * 查询单个实体对象
	 * 
	 * @param  clazz  需要查询的实体类。
	 * @param  id     需要查询的实体对象的主键。
	 * @return Object 查询出来的实体对象。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	/**
     * 查询单个实体对象。
     * 
     * @param   clazz  需要查询的实体类。
     * @param   id     需要查询的实体对象的主键。
     * @return  Object 查询出来的实体对象，对象可能为null。
     */
    public <T> T getObject(Class<T> clazz, Serializable id) {
        return (T) getHibernateTemplate().get(clazz, id);
    }

	/**
	 * 查询全部实体对象
	 * 
	 * @param  clazz 需要查询的实体类。
	 * @return List  查询出来的实体对象集合。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	public List loadObjects(Class clazz) {
		return getHibernateTemplate().loadAll(clazz);
	}

	/**
	 * 查询实体对象组合结果集
	 * 
	 * @param  hql  需要执行的hql语句。
	 * @return List 查询出来的实体对象组合结果集。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	public List queryByHql(final String hql) {
		return getHibernateTemplate().find(hql);
	}
	
	/**
	 * 参数查询
	 * 
	 * @param  hql  需要执行的hql语句。
	 * @param  parammeters 参数集合
	 * @return List 查询出来的实体对象组合结果集对象，包含了分页信息。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	public List queryByHqlParams(final String hql, Map<String, Object> parammeters) {
		
		// 定义参数名称、参数值对象
		Set<String> parameterKeySet = parammeters.keySet();
		String[] parameterNames = new String[parameterKeySet.size()];
		Object[] parameterValues = new Object[parameterKeySet.size()];
		
		// 将参数集合拆分为参数名称数组、值数组，方便调用HibernateTemplate的参数查询方法
		Iterator<String> it = parameterKeySet.iterator();
		int i = 0;
		String keyName;
		while(it.hasNext()){
			keyName = it.next();
			parameterNames[i] = keyName;
			parameterValues[i] = parammeters.get(keyName);
			i +=1;
		}		

		return getHibernateTemplate().findByNamedParam(hql, parameterNames, parameterValues);
	}
	
    /**
     * 分页查询 
     * <p>
     * 使用hibernate提供的方法根据查询语句，查询出实体对象组合结果集。
     * 
     * @param  hql 需要执行的hql语句。
     * @return PageListData 查询出来的实体对象组合结果集对象，包含了分页信息。
     * @since  PASIAM Ver1.0
     */
    public PageListData queryByHqlPages(String hql, PageListData pageListData)
    {
        List list = pageUtil.queryByPage(hql, pageListData);

        // 执行分页查询
        while (list.size() == 0 && pageUtil.getCount() > 0)
        {
            pageListData.setPageNeeded(pageListData.getPageNeeded() - 1);
            list = pageUtil.queryByPage(hql, pageListData);
        }
        pageListData.setCount(pageUtil.getCount());
        pageListData.setDataArray(list);
        return pageListData;
    }	
	
	/**
	 * 使用JDBC的Sql语句进行数据库查询
	 * 
	 * @param  sql  需要执行的sql语句。
	 * @return List 查询出来的实体对象组合结果集对象。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */	
	public List queryByJdbc(String sql){
		return jdbcTemplate.getJdbcOperations().queryForList(sql);
	}
	
	/**
	 * 使用JDBC的Sql语句进行数据库查询
	 * 
	 * @param  sql  需要执行的sql语句。
	 * @param  paramMap 需要的参数以及值
	 * @return List 查询出来的实体对象组合结果集对象。
	 * @author 刘红军
	 * @since  PASIAM Ver1.0
	 */
	public List queryByJdbcParams(String sql, Map paramMap) {
		return jdbcTemplate.queryForList(sql, paramMap);
	}	

	public void setJdbcTemplate(NamedParameterJdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
}
